package com.example.tdemo.design.singleton;

public class Singleton {

    // volatile 防止指令重排
    private static volatile Singleton instance = null;

    private String name;

    private String age;

    private Singleton() {
        System.out.println(Thread.currentThread().getName() + "构造方法");
    }

    private Singleton(String name,String age){
        this.name = name;
        this.age = age;
        System.out.println(Thread.currentThread().getName() + "构造方法");
    }

    // 双重检查加锁
    // 指令重排 会造成其它线程取数据的时候，instance不为null，但是instance的属性可能未初始化完成 直接使用会报错
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class){
                if (instance == null) {
                    // 1 分配内存
                    // 2 创建Singleton对象
                    // 3 设置instance指向刚分配的内存地址
                    // 2 3 1 可能会重排，造成instance不为null，但是instance的属性可能未初始化完成
                    instance = new Singleton("张三","20");
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        // 测试
        for (int i = 0; i < 1000; i++) {
            new Thread(() -> {
                Singleton instance = Singleton.getInstance();
                System.out.println(Thread.currentThread().getName() + ":" + instance);
            }).start();
        }
        //Thread-2:com.example.tdemo.design.singleton.Singleton@4c48e6a8
        //Thread-1:com.example.tdemo.design.singleton.Singleton@6e5802d8
        //Thread-3:com.example.tdemo.design.singleton.Singleton@3a8b3c40
    }
}
